package se.perp.c4.control;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import se.perp.c4.control.iface.IMenuListener;
import se.perp.c4.model.Actor;
import se.perp.c4.model.ActorCollection;
import se.perp.c4.model.Game;
import se.perp.c4.model.TerritoryCollection;
import se.perp.c4.ui.ActorViewer;
import se.perp.c4.ui.Images;
import se.perp.c4.ui.MainMenu;
import se.perp.c4.ui.MainWindow;
import se.perp.c4.ui.MessageBox;
import se.perp.c4.ui.PieceCollection;
import se.perp.c4.ui.Portraits;
import se.perp.c4.ui.StartClientDialog;
import se.perp.c4.ui.StartServerDialog;

class MainWindowListener implements IMenuListener, WindowListener {

    private MainWindow mainWindow;
    private ActorCollection actorColl = null;
    private TerritoryCollection terrColl = null;
    private PieceCollection pieceColl = null;
    private ActorViewer actorViewer;
    private final Properties properties;

    /**
     * @param av should be the same instance as was placed on the main panel,
     * used for forwarding to the placement panel.
     */
    public MainWindowListener(MainWindow mw, PieceCollection pc, TerritoryCollection tc,
            ActorCollection ac, ActorViewer av, Properties properties) {
        mainWindow = mw;
        pieceColl = pc;
        terrColl = tc;
        actorColl = ac;
        actorViewer = av;
        this.properties = properties;

    }

    public void gameExit() {
        if (Status.gameIsOn) {
            int reply = MessageBox.yesNo(mainWindow, "There's a game currently in progress!\n\n" +
                    "Are you sure you want to exit?", "Exit", Portraits.getIcon(Actor.EActor.FRODO), true);
            if (reply != JOptionPane.YES_OPTION) {
                return;
            }
        }

        try {
            OutputStream os = new FileOutputStream("confrontation.xml", false);
            properties.storeToXML(os, "Confrontation settings");
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(mainWindow, "Encountered an error while trying to save the configurations file.\nYour current settings will not be saved. Sorry!", "Error", JOptionPane.ERROR_MESSAGE);
        }

        System.exit(0);
    }

    public void helpAbout() {
        MessageBox.ok(mainWindow,
                "Confrontation " + Main.VERSION + "\n" +
                Main.BUILD_DATE + "\n\n" +
                "A computerized version of the Reiner Knizia board game\n" +
                "Lord of the Rings: The Confrontation" +
                "\n\nBy Per Pettersson (ostybosty@hotmail.com)",
                "About Confrontation", Images.CONFRONTATION, true);
    }

    public void gameAsClient(MainMenu mainMenu) {
        mainMenu.setGameAsClientEnabled(false);
        mainMenu.setGameAsServerEnabled(false);
        String nameStr = properties.getProperty("playername");
        String ipStr = properties.getProperty("ip");
        String portStr = properties.getProperty("port");
        StartClientDialog dlg = new StartClientDialog(mainWindow, mainMenu, nameStr, ipStr, portStr);
        StartClientDialog.Choice choice = dlg.getChoice();
        if (choice == StartClientDialog.Choice.CANCEL) {
            return;
        }

        String playerName = dlg.getPlayerName();
        String host = dlg.getIP();
        int port = dlg.getPortNumber();

        properties.setProperty("playername", playerName);
        properties.setProperty("ip", host);
        properties.setProperty("port", String.valueOf(port));

        GameController controller = new GameController(
                mainWindow, pieceColl, actorColl, terrColl, actorViewer, playerName);
        ConnectionCreator.createClient(mainWindow, mainMenu, host, port, controller);
    }

    public void gameAsServer(MainMenu mainMenu) {
        mainMenu.setGameAsClientEnabled(false);
        mainMenu.setGameAsServerEnabled(false);
        String nameStr = properties.getProperty("playername");
        String portStr = properties.getProperty("port");
        Game.ShelobRule shelobRule;
        try {
            shelobRule = Game.ShelobRule.valueOf(properties.getProperty("shelobrule"));
        } catch (Exception e) {
            shelobRule = Game.ShelobRule.SHELOB_STAYS;
        }
        StartServerDialog dlg = new StartServerDialog(mainWindow, mainMenu, nameStr, portStr, shelobRule);
        StartServerDialog.Choice choice = dlg.getChoice();
        if (choice == StartServerDialog.Choice.CANCEL) {
            return;
        }

        String playerName = dlg.getPlayerName();
        int port = dlg.getPortNumber();
        shelobRule = dlg.getShelobRule();
        String shelobStr = shelobRule.toString();

        properties.setProperty("playername", playerName);
        properties.setProperty("port", String.valueOf(port));
        properties.setProperty("shelobrule", shelobStr);

        GameController controller = new GameController(
                mainWindow, pieceColl, actorColl, terrColl, actorViewer, playerName);
        controller.setShelobRule(shelobRule);
        ConnectionCreator.createServer(mainWindow, mainMenu, port, controller);
    }

    public void gameAgainstBot(JMenu gameMenu) {
//        IConnection bot = BotFactory.createBot();
//
//        IConnectionListener controller = new GameController(mainWindow, pieceColl, actorColl, terrColl, actorViewer, "Foobar");
//        controller.gotConnection(bot);
    }

    @Override
    public void windowClosing(WindowEvent e) {
        gameExit();
    }

    public void windowOpened(WindowEvent e) {
    }

    public void windowClosed(WindowEvent e) {
    }

    public void windowIconified(WindowEvent e) {
    }

    public void windowDeiconified(WindowEvent e) {
    }

    public void windowActivated(WindowEvent e) {
    }

    public void windowDeactivated(WindowEvent e) {
    }
}
